'use strict';

const log = require('@imooc-cli-dev/log');
const Package = require('@imooc-cli-dev/package');
const init = require('@imooc-cli-dev/init');
const CACHE_PATH = 'dependencies'
const path = require('path')
const cp = require('child_process');


const SETTINGS = {
  init: '@imooc-cli/init'
}
async function exec() {
  // 如果这边target_path 之所以要用全局变量是，防止有多层嵌套的命令用到
  // 这个值，
  let targetPath = process.env.CLI_TARGET_PATH;
  let homePath = process.env.CLI_HOME_PATH;
  let storePath,pkg;
  log.verbose('homePath', homePath)
  log.verbose('targetPath', targetPath)
  
  const commandItem = arguments[arguments.length - 1];
  // Command 对象的.name 获取name
  const packageName = SETTINGS[commandItem.name()]

  const packageNameVersion = 'latest';
  if(!targetPath) {
    targetPath = path.resolve(homePath, CACHE_PATH);
    storePath = path.resolve(targetPath, 'node_modules');
    pkg = new Package({
      packageName,
      storePath,
      packageNameVersion,
      targetPath
    });
    
    if(await pkg.exists()) {
      await pkg.update()
    } else {
      await pkg.install()
    }
  } else {
    pkg = new Package({
      packageName,
      packageNameVersion,
      targetPath
    })
  }

  const filePath = pkg.getRootFilePath();
  if(filePath) {
    try {
      const args = Array.from(arguments);
      const o = Object.create(null);
      const cmd = args[args.length - 1];

      // 对command实例进行精简
      Object.keys(cmd).forEach(item => {
        if(cmd.hasOwnProperty(item) && !item.startsWith('_') && item!=='parent') {
          o[item] = cmd[item]
        }
      })

      args[args.length - 1] = o;
      let code = `require("${filePath}").call(null, ${JSON.stringify(args)})`;
      const child = spawn('node', ['-e', code], {
        cwd: process.cwd(),
        stdio: 'inherit' // 默认pipe 需要通过stdin，stdout，stderr 使用
      })

      // 不使用stdio: 'inherit',需要做的
      // child.stdout.on('data', function(chunk){
        // console.log(chunk)
      // })
      // 不使用stdio: 'inherit'
      // child.stderr.on('data', function(chunk){
        // console.log(chunk)
      // })

      child.on('error', e => {
        log.error(e.message)
        process.exit(1)
      })

      child.on('exit', e => {
        log.verbose('initCommand命令执行成功'+e)
        process.exit(e)
      })

    } catch (error) {
      log.error(colors.red(error.message))
    }
    // 这里是在当前进程中直接调用
    // require(filePath).call(null, Array.from(arguments)) // 这边需要的就是一个对象
    // 我们可以在node的子进程中调用
  } else {
    throw '请确认执行targetPath的传入是否正确'
  }
}

function spawn(command, args, options) {
  const win32 = process.platform === 'win32';
  const cmd = win32 ?  'cmd' : command;
  const cmdArgs = win32 ? ['/c'].concat(command, args) : args;
  return cp.spawn(cmd, cmdArgs, options || {})

}
module.exports = exec;
